<template>
  <div class="main">
    <div class="main-top">
      <div class="main-controls-select">
        <div class="main-controls-select-text">通量</div>
        <div class="main-controls-select-content">
          <el-select
            v-model="selectedFlux"
            size="small"
            placeholder="选择通量类型"
          >
            <el-option label="CO₂摩尔通量" value="co2" />
            <el-option label="CH₄通量" value="ch4" />
            <el-option label="潜热通量" value="le" />
            <el-option label="显热通量" value="h" />
            <!-- 可以根据需要添加更多气体类型 -->
          </el-select>
        </div>
      </div>
      <div class="main-controls-datePicker">
        <el-date-picker
          v-model="selectedTimeRange"
          size="small"
          type="datetimerange"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          format="YYYY-MM-DD HH:mm"
          value-format="YYYY-MM-DD HH:mm"
          :disabled-date="disabledDate"
        />
      </div>
    </div>
    <div class="main-bottom">
      <div ref="chartRef" class="main-bottom-chart"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from "vue";
import * as echarts from "echarts";
import { findFluxByTimeRange, findFluxInLatestDayData } from "@/api/flux.js";

// 过滤掉无效数据(value[1]为null或undefined)
function filterVaildData(data) {
  return data.filter(
    (item) => item.value[1] !== null && item.value[1] !== undefined
  );
}

// 选择器的绑定值
const selectedTimeRange = ref([]); // 默认时间范围
const selectedFlux = ref("co2"); // 默认通量类型

// 自定义数据
let customDataBeforeFilter = [
  { name: "2024-01-01 08:30", value: ["2024-01-01 08:30", -4.7356] },
  { name: "2024-01-01 09:00", value: ["2024-01-01 09:00", -5.6685] },
  // 添加更多数据点
];

// 禁用当前时间之后的日期
const disabledDate = (time) => {
  const now = new Date();
  return time.getTime() > now.getTime();
};

// 过滤无效数据
let customData = filterVaildData(customDataBeforeFilter);

// 通量类型与单位的映射关系
const fluxUnitMap = {
  co2: "μmol/m²/s",
  ch4: "μg/m²/s",
  le: "W/m²",
  h: "W/m²",
};

// 通量类型与标题的映射关系
const fluxLabelMap = {
  co2: "CO₂摩尔通量",
  ch4: "CH₄通量",
  le: "潜热通量",
  h: "显热通量",
};

const chartRef = ref(null);

const initChart = () => {
  // 检查是否已经存在实例
  const existingChart = echarts.getInstanceByDom(chartRef.value);
  let myChart = existingChart || echarts.init(chartRef.value);

  // 动态获取 Y 轴单位
  const yAxisUnit = fluxUnitMap[selectedFlux.value] || "未知单位";

  // 动态获取标题内容
  const titleText = `${fluxLabelMap[selectedFlux.value]} 监测数据统计趋势`;

  // 计算数据的最大值和最小值
  const dataValues = customData
    .map((item) => item.value[1])
    .filter((value) => value !== null && value !== undefined);

  // 获取最大值加上百分之5的空间，保留小数点后三位
  const maxValue = Math.max(...dataValues) >= 0
    ? (Math.max(...dataValues) * 1.05).toFixed(2)
    : (Math.max(...dataValues) * 0.95).toFixed(2);
  // 获取最小值扩大5%的空间按，保留小数点后两位
  const minValue = Math.min(...dataValues) >= 0
    ? (Math.min(...dataValues) * 0.95).toFixed(2)
    : (Math.min(...dataValues) * 1.05).toFixed(2);

    
  // 配置实例
  const option = {
    // 图例在父容器中所占位置
    grid: {
      top: "13%",
      left: "1%",
      right: "2%",
      bottom: "2%",
      // 是否包含坐标轴的刻度标签
      containLabel: true,
    },
    // // 标题
    // title: {
    //   text: titleText,
    //   left: "center", // 标题居中
    //   top: "5%", // 标题距离顶部5%
    //   textStyle: {
    //     fontSize: 18,
    //     color: "#1e90ff",
    //   },
    // },
    // 提示框组件
    tooltip: {
      trigger: "axis", // 触发类型
      // 格式化提示框内容
      formatter: function (params) {
        params = params[0];
        const value = params.value[1] !== null ? params.value[1].toFixed(2) : "无数据";
        return `${params.axisValueLabel} : <span style="color: rgb(23, 192, 235); font-weight: bold">${value}</span>`;
      },
      // 提示框样式
      axisPointer: {
        animation: false,
        type: "cross", //十字准星指示器
        // x轴的线条
        crossStyle: {
          color: "rgba(76, 155, 253)", //线的颜色
          width: 1.5, // 宽度
          type: "dashed", // 虚线
        },
        // y轴的线条
        lineStyle: {
          color: "rgba(76, 155, 253)",
          width: 1.5,
          type: "dashed",
        },
        // x和y轴指向的数据提示样式
        label: {
          show: true,
          color: "#fff", // 文字颜色
          backgroundColor: "#4c9bfd", // 背景颜色
        },
      },
    },
    xAxis: {
      show: true,
      type: "time",
      splitLine: {
        show: false,
      },
      axisLine: {
        //坐标轴颜色
        lineStyle: {
          color: "#f1f2f6",
        },
      },
      axisLabel: {
        show: true,
        color: "#f1f2f6",
        fontSize: 14,
        interval: 0,
        formatter: function (value) {
          const date = new Date(value);
          const hours = date.getHours().toString().padStart(2, "0");
          const minutes = date.getMinutes().toString().padStart(2, "0");

          // 每隔两个小时显示一次时间
          if (hours % 4 === 0 && minutes === "00") {
            if(hours === "00"){
              return `${date.getMonth() + 1}-${date.getDate()}`;
            }
            else{
              return `${hours}:${minutes}`;
              // 隔天显示日期
            }
          } else {
            return "";
          }
        },
      },
    },
    yAxis: {
      type: "value",
      name: yAxisUnit, // 动态设置 Y 轴单位
      nameLocation: "end", // name的具体位置，可调整上中下左
      nameTextStyle: {
        align: "left",
        verticalAlign: "top",
      },
      boundaryGap: [0, "100%"], // 坐标轴两端空白策略, 保证数据点不会被遮挡
      axisLine: {
        show: true,
        //线
        lineStyle: {
          color: "#f1f2f6",
          width: 2,
        },
      },
      splitLine: {
        //网格区域
        show: true,
        lineStyle: {
          color: "rgba(25, 232, 35, 0.1)",
          width: 1,
          type: "solid",
        },
      },
      axisLabel: {
        show: true,
        color: "#f1f2f6", //更改坐标轴文字颜色
        fontSize: 14, //更改坐标轴文字大小
      },
      // 动态设置 Y 轴范围
      min: minValue,
      max: maxValue,
    },
    dataZoom: [
      {
        type: "inside", // 内置型数据区域缩放组件
        zoomOnMouseWheel: true, // 滚轮触发缩放
        moveOnMouseMove: true, // 鼠标移动时触发平移
        moveOnMouseWheel: true, // 滚轮滚动时触发平移
      },
    ],
    series: [
      {
        name: "Data",
        type: "line",
        showSymbol: true, // 显示数据点标记
        symbol: "circle", // 数据点标记形状
        symbolSize: 5, // 数据点标记大小
        data: customData.map((item) => item.value), // 直接加载所有数据
        // 折线的样式
        itemStyle: {
          color: "rgba(25, 232, 35, 1)", // 折线点的颜色
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            {
              offset: 0,
              color: "rgba(44, 233, 53, 0.9)", // 0% 处的颜色
            },
            {
              offset: 1,
              color: "rgba(169, 236, 173, 0.3)", // 100% 处的颜色
            },
          ]), //背景渐变色
        },
        // 折线的样式
        lineStyle: {
          width: 2,
          type: "solid",
          color: "rgba(25, 232, 35, 1)", //折线的颜色
        },
        smooth: true, // 折线平滑
      },
    ],
  };
  // 载入实例
  myChart.setOption(option);
  window.addEventListener("resize", () => {
    myChart.resize();
  });
};

// 查询数据通过时间范围
const queryDataByTimeRange = async (startTime, endTime, fluxType) => {
  try {
    let result = await findFluxByTimeRange(startTime, endTime);
    // 保存数据
    // 将获得的数据类型变为自定义数据类型
    customDataBeforeFilter = result.data.map((item) => {
      let fluxValue;
      if (fluxType === "co2") {
        fluxValue = item.fc; // 对应 CO₂ 的字段
      } else if (fluxType === "ch4") {
        fluxValue = item.fch4; // 对应 CH₄ 的字段
      } else if (fluxType === "le") {
        fluxValue = item.le; // 对应 le 的字段
      } else if (fluxType === "h") {
        fluxValue = item.h; // 对应 h 的字段
      }
      return {
        name: item.timestamp,
        value: [item.timestamp, fluxValue],
      };
    });
    // 过滤无效数据
    customData = filterVaildData(customDataBeforeFilter);
  } catch (error) {
    console.error(error);
  }
};

// 查询默认最新日期数据
const queryFluxLatestData = async () => {
  try {
    let result = await findFluxInLatestDayData();
    // 获取第一个数据点的 timestamp 作为起始时间
    const startTime = result.data[0].timestamp;
    // 获取最后一个数据点的 timestamp 作为结束时间
    const endTime = result.data[result.data.length - 1].timestamp;

    // 设置 selectedTimeRange 的默认值
    selectedTimeRange.value = [startTime, endTime];

    // 将获得的数据类型变为自定义数据类型
    customDataBeforeFilter = result.data.map((item) => {
      return {
        name: item.timestamp,
        value: [item.timestamp, item.fc],
      };
    });

    // 过滤无效数据
    customData = filterVaildData(customDataBeforeFilter);
    initChart();
  } catch (error) {
    console.error(error);
  }
};

// 监听选择器的变化
watch(
  [selectedTimeRange, selectedFlux],
  async ([newTimeRange, newFlux]) => {
    if (newTimeRange && newTimeRange.length === 2) {
      const [startTime, endTime] = newTimeRange;
      await queryDataByTimeRange(startTime, endTime, newFlux);
      // 清除原有实例数据
      echarts.dispose(chartRef.value);
      // 重新初始化图表
      initChart();
    }
  },
  { immediate: true }
);

// 初始钩子函数
onMounted(() => {
  // 请求接口获得最新日期flux数据
  queryFluxLatestData();
  // 测试接口
  // findMeteorologyInLatestDayData().then((res) => {
  //   console.log(res);
  // });
});
</script>
<style scoped lang="scss">
.main {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  .main-top {
    margin-top: 0.5vh;
    height: 7%;
    display: flex;
    align-items: center; /* 垂直居中 */
    justify-content: space-around; /* 水平间距 */
    padding: 1vh;
    .main-controls-select {
      display: flex;
      align-items: center; /* 垂直居中 */
      width: 40%; /* 设置为占父容器的 40% */
      justify-content: space-between;
      .main-controls-select-text {
        width: 20%;
        display: flex;
        font-size: 1.8vh;
        color: #1e90ff;
        // 字体加粗
        font-weight: bold;
      }
      .main-controls-select-content {
        display: flex;
        width: 80%;
      }
    }
    .main-controls-datePicker {
      display: flex;
      width: 57%; /* 设置为占父容器的 60% */
    }
  }
  .main-bottom {
    height: 93%;
    display: flex;
    align-items: center; /* 垂直居中 */
    justify-content: center; /* 水平居中 */
    .main-bottom-chart {
      width: 100%;
      height: 100%;
    }
  }
}
</style>